package com.varian.mybatis.config;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.varian.mybatis.handler.MybatisMetaObjectHandler;
import com.varian.mybatis.handler.VarianMetaObjectHandler;
import com.varian.tool.exception.ServerException;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * @author ben
 * @since 2024/6/23
 */
@AutoConfiguration
public class MybatisAutoConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

    @Bean
    public VarianMetaObjectHandler varianMetaObjectHandler(@Lazy List<MybatisMetaObjectHandler> handlers) {
        return new VarianMetaObjectHandler(handlers);
    }

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer mybatisJackson2ObjectMapperBuilderCustomizer() {
        return builder -> builder.serializerByType(IPage.class, new StdSerializer<>(IPage.class) {
            @Override
            @SuppressWarnings("unchecked")
            public void serialize(IPage value, JsonGenerator gen, SerializerProvider provider) throws IOException {
                // 开始写入对象
                gen.writeStartObject();
                // current
                gen.writeNumberField("current", value.getCurrent());
                // size
                gen.writeNumberField("size", value.getSize());
                // total
                gen.writeNumberField("total", value.getTotal());
                // records
                gen.writeArrayFieldStart("records");
                CollUtil.defaultIfEmpty(value.getRecords(), Collections.emptyList())
                        .forEach(record -> {
                            try {
                                gen.writeObject(record);
                            } catch (IOException e) {
                                throw ServerException.of(e.getMessage());
                            }
                        });
                gen.writeEndArray();
                gen.writeEndObject();
            }
        });
    }
}
